题目如下 :
这题可以用广度优先搜索的算法来解决,首先,没移动一次有三个选择,给出起始点和最终点,那么我们只需要枚举出全部的解决方案,然后比较出最短的方案就可以了,但是这样很浪费时间空间,复杂度很高,实际上用不了,而搜索树可以简化搜索,广度优先是从搜索树从上往下扫描的,那么我在搜索的时候建立一个保存这个位置是否到达过的标记,用一个长度为n的一维数组来保存,因为我在入队的时候,到达相同位置,第一次扫描到的用的步数肯定比之后扫描到的情况要少,所以相同位置只入队一次,这样可以很大的优化性能,按照广度优先搜索的套路,代码如下:
import java.util.*;
class Point2{
int step = 0,x=0;
public Point2(){
}
public Point2(int x,int step){
this.x=x;
this.step = step;
}
}
public class MoveDemo {
static int n=0,A=0,B=0,result=0;
static int[] oprate = {1,-1,2};
static int[] visit = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
n=sc.nextInt();
A=sc.nextInt();
B=sc.nextInt();
visit = new int[n+1];
bfs(A);
System.out.print(result);
}
public static void bfs(int a){
Queue<Point2> queue = new LinkedList<Point2>();
visit[a] = 1;
queue.offer(new Point2(a,0));
int flag = Math.abs(A-B);
while(!queue.isEmpty()){
Point2 temp = queue.poll();
boolean find = false;
for(int i=0;i<3;i++){
if(i==2){
if(temp.x*2<=n){
if(temp.x*2==B){
result = temp.step+1;
find = true;
break;
}
if(visit[temp.x*2]==0){
visit[temp.x*2]=1;
queue.offer(new Point2(temp.x*2,temp.step+1));
}
}
}else{
if(temp.x+oprate[i]<=n){
if(temp.x+oprate[i] == B){
result = temp.step+1;
find = true;
break;
}
if(visit[temp.x+oprate[i]]==0){
visit[temp.x+oprate[i]]=1;
queue.offer(new Point2(temp.x+oprate[i],temp.step+1));
}
}
}
}
if(find){
break;
}
}
}
}